using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Awesome.Extensions.Monads.Maybe;

namespace Awesome.Extensions.Reflection
{
    internal static class MethodInfoProvider
    {
        [DebuggerStepThrough]
        public static MethodInfo FromDelegate(Delegate @delegate)
        {
            return @delegate.Method;
        }

        [DebuggerStepThrough]
        public static MethodInfo FromExpression<T>(Expression<T> expression)
        {
            var method = expression
                .With(e => e.Body as UnaryExpression)
                .With(e => e.Operand as MethodCallExpression)
                .With(e => e.Arguments.ElementAtOrDefault(2))
                .With(a => a as ConstantExpression)
                .With(a => a.Value as MethodInfo);

            if (method == null)
            {
                throw new ArgumentException("Error: expression must be in correct format: x => x.Method");
            }

            return method;
        }
    }
}